/**
 * 
 */
package name.yzhu.wordsearch;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * this class is used to parse the word list file and construct a {@link CharMatrix}</br>
 * the example is below:
 * <pre>
   5 5

   NO_WRAP

   ABCDE
   FGHIJ
   KLMNO
   PQRST
   UVWXY
 *</pre>
 *and that means this line is comment if the line beginning with # 
 * @author yhzhu
 *
 */
public class WordList {

	private CharMatrix charMatrix = null;
	private SearchMode searchMode = SearchMode.UNKNOWN;
	
	private WordList(CharMatrix charMatrix, SearchMode searchMode) {
		this.charMatrix = charMatrix;
		this.searchMode = searchMode;
	}
	
	/**
	 * construct a wordList 
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	static public WordList getWordListFactory(String fileName) throws IOException{
		return getWordListFactory(new File(fileName));
	}
	/**
	 * construct a wordList 
	 * @param file  word list file name
	 * @return
	 * @throws IOException
	 */
	static public WordList getWordListFactory(final File file) throws IOException{
		BufferedReader reader = null;
		CharMatrix charMatrix = null;
		SearchMode searchMode = SearchMode.UNKNOWN;
	     try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(file), "utf-8"));
			String rowColumn = null;
			String flag = null;
			String line = null;
			int count = 0;
			while (null != (line = reader.readLine())){
				// this line is empty or comments
				if (line.trim().equals("") || line.startsWith("#")) 
					continue;
				
				if (null == rowColumn){
					rowColumn = line;
					String[] str = rowColumn.split("\\s");
					if (str.length != 2)
						throw new IOException("invalid word list format, the line is "+line);
					charMatrix = new CharMatrix(Integer.parseInt(str[0]),
							Integer.parseInt(str[1]));
				}
				else if (null == flag){
					flag = line;
					searchMode = SearchMode.byStrToMode(flag);
				}
				else {
					//the word will be truncated if the word is longer than the column which is set in the beginning with the file
					if (line.length() > charMatrix.getColumn())
						line = line.substring(0, charMatrix.getColumn());
					charMatrix.addWord(line);
					count++;
				}
				
				//the lines will be ignored if the line is exceed th row number that is set on the begin of the file 
				if (charMatrix != null && count == charMatrix.getRow()) 
					break;
			}
			return new WordList(charMatrix, searchMode);
		} catch (Exception e) {	
		   throw new IOException(e);
		}
	    finally{
	    	if (null != reader){
	    		reader.close();
	    	}
	    }
	}

	public CharMatrix getCharMatrix() {
		return charMatrix;
	}

	public SearchMode getSearchMode() {
		return searchMode;
	}
}
